package com.my.house.common.utils;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.my.house.common.Constants;
import com.my.house.domain.User;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * 线程本地绑定变量参数相关工具类
 * 使用的ali的可传递到子线程绑定变量的工具
 * 如果在attend6du-core里使用，要注意sync项目里没有注入登录用户的问题
 * @author yangll
 */
public class ThreadLocalHolder {
    private static final TransmittableThreadLocal<Map<String, Object>> LOCAL = new TransmittableThreadLocal<>();

    /**
     * 缓存本次请求线程绑定参数数据
     * @param key 关键字
     * @param value 值
     */
    public static void set(String key, Object value) {
        Map<String, Object> map = getLocalMap();
        map.put(key, value);
    }

    /**
     * 获取本次缓存线程绑定参数数据
     * @param key 关键字
     */
    public static Object get(String key) {
        Map<String, Object> map = getLocalMap();
        return map.get(key);
    }

    /**
     * 获取本次线程里设置的所有参数键值对
     * @return all键值对
     */
    public static Map<String, Object> getLocalMap() {
        Map<String, Object> map = LOCAL.get();
        if (Objects.isNull(map)) {
            map = new HashMap<>();
            LOCAL.set(map);
        }
        return map;
    }

    /**
     * 获取当前登录用户
     * @return 用户ID
     */
    public static User getUser() {
        Object object = get(Constants.USER);
        if (Objects.nonNull(object) && object instanceof User user) {
            return user;
        }
        return null;
    }

    /**
     * 获取当前登录用户ID
     * @return 用户ID
     */
    public static Long getUserId() {
        User user = getUser();
        return Optional.ofNullable(user).map(User::getId).orElse(0L);
    }

    /**
     * 设置当前登录用户
     * @param user 用户
     */
    public static void setUser(User user) {
        set(Constants.USER, user);
    }

    /**
     * 清空线程绑定变量
     */
    public static void remove() {
        LOCAL.remove();
    }

    /**
     * 清除线程里某个变量
     * @param key 键值
     */
    public static void remove(String key) {
        LOCAL.get().remove(key);
    }

}
